分类
联系方式
  1. 新浪微博
  2. E-mail

Racket 列表

pair

pair 包含两个值。通过 const 构建 pair。通过car 获取第一个值。通过 cdr 获取第二个值。

构建

> (cons 'x 'y)
'(x . y)

> '(10 . 20)
'(10 . 20)

可以看到 pair 的表示形式,两个值之间有一个点(.)。

取值

> (define pair (cons 10 20))
> (car pair)
10

> (cdr pair)
20

列表 list

列表可以认为是由 pair 通过链表组合而成。

列表通常表现形式是以 ' 为开头的括号,内部封装元素。

创建

> (define l (list 234 123 68 74 100 1 3 5 8 4 2))

列表操作

length 长度

> (length l)
11

list-ref 索引选择

> (list-ref (list 'a 'b 'c) 0)
'a

> (list-ref (list 'a 'b 'c) 1)
'b

> (list-ref (list 'a 'b 'c) 2)
'c

list-tail 按索引截取

> (list-tail (list 1 2 3 4 5) 2)
'(3 4 5)

> (list-tail (cons 1 2) 1)
2

append 拼接

> (append (list 1 2) (list 3 4))
'(1 2 3 4)

> (append (list 1 2) (list 3 4) (list 5 6) (list 7 8))
'(1 2 3 4 5 6 7 8)

reverse 反转

> (reverse (list 1 2 3 4))
'(4 3 2 1)

列表迭代

map 映射

> (map (lambda (i) (/ 1 i))
       '(1 2 3))
'(1 1/2 1/3)

andmap 和 ormap

对每个元素,根据 lambda 进行逻辑判断:

> (andmap (lambda (i) (i . < . 3))
         '(1 2 3))
#f

> (ormap (lambda (i) (i . < . 3))
         '(1 2 3))
#t

for-each 遍历

> (for-each (lambda (i) (display i))
            '(1 2 3))
123

foldl 和 foldr 折叠

foldl 是从左到右,foldr 是从右到左。

> (foldl (lambda (v i) (+ v i))
         10
         '(1 2 3))
16

foldr:

> (foldr (lambda (v l) (cons (add1 v) l)) '() '(1 2 3 4))
'(2 3 4 5)

理解:

  • foldr 接收 3 个参数:一个函数,一个初始值,一个序列
  • 从右往左依次对元素中每一个参数调用函数
  • 将结果与下一个参数一起再传给函数

过程:

  • 取出 4,参数为 v=4 和 l='(),得到 '(5)
  • 取出 3,参数为 v=3 和 l='(5),得到 '(4 5)
  • 取出 2,参数为 v=2 和 l='(4 5),得到 '(3 4 5)
  • 取出 1,参数为 v=1 和 l='(3 4 5),得到 '(2 3 4 5)

列表过滤

filter 过滤

> (filter (lambda (i) (i . < . 3))
          '(1 2 3))
'(1 2)

remove 元素删除

删除首个遇到的元素:

> (remove 2 (list 1 2 3 2 4))
'(1 3 2 4)

> (remove '(2) (list '(1) '(2) '(3)))
'((1) (3))

> (remove "2" (list "1" "2" "3"))
'("1" "3")

> (remove #\c (list #\a #\b #\c))
'(#\a #\b)

> (remove "B" (list "a" "A" "b" "B") string-ci=?)
'("a" "A" "B")

> (remove 5 (list 1 2 3 2 4))
'(1 2 3 2 4)

remove* 元素删除

删除所有遇到的元素:

> (remove* (list 1 2) (list 1 2 3 2 4 5 2))
'(3 4 5)

sort 排序

> (sort '(1 3 4 2) <)
'(1 2 3 4)

> (sort '("aardvark" "dingo" "cow" "bear") string<?)
'("aardvark" "bear" "cow" "dingo")

> (sort '(("aardvark") ("dingo") ("cow") ("bear"))
        #:key car string<?)
'(("aardvark") ("bear") ("cow") ("dingo"))

列表搜索

member 按元素截取

> (member 2 (list 1 2 3 4))
'(2 3 4)

> (member 9 (list 1 2 3 4))
#f

> (member #'x (list #'x #'y) free-identifier=?)
'(#<syntax:eval:569:0 x> #<syntax:eval:569:0 y>)

> (member #'a (list #'x #'y) free-identifier=?)
#f

> (member 'b '(a b . etc))
'(b . etc)

findf 搜索首个满足条件

> (findf (lambda (arg)
           (> arg 9))
         '(7 8 9 10 11))
10

assoc 条件截取

> (assoc 3 (list (list 1 2) (list 3 4) (list 5 6)))
'(3 4)

> (assoc 9 (list (list 1 2) (list 3 4) (list 5 6)))
#f

> (assoc 3.5
         (list (list 1 2) (list 3 4) (list 5 6))
         (lambda (a b) (< (abs (- a b)) 1)))
'(3 4)

列表附加方法

empty 空列表

> empty
'()

> (eq? empty null)
#t

empty? 是否为空

> (empty? '(1 2))
#f

> (empty? '())
#t

fisrt 获取首元素

> (first l)
234

rest 剔除首元素

> (rest l)
'(123 68 74 100 1 3 5 8 4 2)

second...tenth

获取第二、……、第十个元素。

take 取前 N 个元素

> (take l 4)
'(234 123 68 74)

drop 剔除前 N 个元素

> (drop l 4)
'(100 1 3 5 8 4 2)

在第 N 个元素处分成两半:

> (split-at l 4)
'(234 123 68 74)

'(100 1 3 5 8 4 2)

条件选取:

> (takef l even?)
'(234)

条件剔除:

> (dropf l even?)
'(123 68 74 100 1 3 5 8 4 2)

列表去重:

> (remove-duplicates '(1 2 3 2 4 5 1))
'(1 2 3 4 5)

按照条件分成两半:

> (partition (lambda (x) (< x (first l))) l)
'(123 68 74 100 1 3 5 8 4 2)

'(234)

是否是列表

通过 list? 来识别列表,通过 null? 来识别空列表。